package com.kehutong.charge.service.impl;

import com.kehutong.charge.entity.ChargeUrgingConfig;
import com.kehutong.charge.entity.ChargeUrgingEmployee;
import com.kehutong.charge.entity.ChargeUrgingManage;
import com.kehutong.charge.entity.ChargeUrgingUser;
import com.kehutong.charge.service.ChargeArrearsService;
import com.kehutong.charge.service.ChargeUrgingService;
import com.kehutong.charge.util.CommonUtil;
import com.kehutong.charge.util.enums.*;
import com.kehutong.charge.vo.ChargeBillItemsVO;
import com.kehutong.charge.vo.ChargeUrgingManageExcelVO;
import com.kehutong.charge.vo.FeeMsgDetailVO;
import com.kehutong.common.DoveClient;
import com.kehutong.common.constant.CommonConstant;
import com.kehutong.common.dto.UniformSendReqDto;
import com.kehutong.common.entity.Root;
import com.kehutong.common.enums.MessageBusinessEnum;
import com.kehutong.common.enums.TemplateType;
import com.kehutong.common.errcode.Assert;
import com.kehutong.common.errcode.Result;
import com.kehutong.common.excel.tool.ExcelTool;
import com.kehutong.common.urlconfig.WebUrlConfig;
import com.kehutong.common.util.BigDecimalUtils;
import com.kehutong.common.util.ListUtils;
import com.kehutong.common.util.TemplateReplaceUtil;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.orm.jdbc.connection.ThreadLocalCache;
import org.coraframework.orm.jdbc.execute.entity.FindPage;
import org.coraframework.orm.util.Enums;
import org.coraframework.util.Objects;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @program: kht
 * @description: ChargeUrgingServiceImpl
 * @author: joneron
 * @create: 2021/6/30
 **/
public class ChargeUrgingServiceImpl implements ChargeUrgingService {

    private static final Logger logger = LoggerFactory.getLogger(ChargeUrgingServiceImpl.class);

    @Inject
    private JdbcSession jdbcSession;
    @Inject
    private ExcelTool excelTool;
    @Inject
    private DoveClient doveClient;
    @Inject
    private ChargeArrearsService chargeArrearsService;
    @Inject
    private WebUrlConfig webUrlConfig;


    @Override
    public Object configInit() throws Exception {
        JSONArray array = getCorps();
        if(Objects.nonEmpty(array)) {
            for (Object obj : array) {
                JSONObject corp = (JSONObject) obj;

                String corpId = corp.getString("id");
                if (corpId.equals(Root.ROOT_ID)) {
                    continue;
                }

                ThreadLocalCache.current().setCorpId(corpId);

                List<String> list = new ArrayList<>();
                list.add("2-1");
                list.add("2-2");
                list.add("2-3");

                try{
                    ChargeUrgingConfig config1 = Pool.get(ChargeUrgingConfig.class, "1");
                    if (Objects.isNull(config1)) {
                        config1 = Pool.newInstance(ChargeUrgingConfig.class, "1");
                        config1.setCommunityNo("1");
                        config1.setCommunityName(CommonConstant.DEFAULT_COMMUNITY_NAME);
                        config1.setUrgingDate(ChargeUrgingLadderEnum.URGING_LADDER_TWO);
                        config1.setTypeMsgList(list);
                        config1.setStatus(true);
                        config1.setCreateName("系统");
                        jdbcSession.insert(config1);
                    }
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }


                try{
                    ChargeUrgingConfig config2 = Pool.get(ChargeUrgingConfig.class, "2");
                    if (Objects.isNull(config2)) {
                        config2 = Pool.newInstance(ChargeUrgingConfig.class, "2");
                        config2.setCommunityNo("1");
                        config2.setCommunityName(CommonConstant.DEFAULT_COMMUNITY_NAME);
                        config2.setUrgingDate(ChargeUrgingLadderEnum.URGING_LADDER_THREE);
                        config2.setTypeMsgList(list);
                        config2.setStatus(true);
                        config2.setCreateName("系统");
                        jdbcSession.insert(config2);
                    }
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }

                try{
                    ChargeUrgingConfig config3 = Pool.get(ChargeUrgingConfig.class, "3");
                    if (Objects.isNull(config3)) {
                        config3 = Pool.newInstance(ChargeUrgingConfig.class, "3");
                        config3.setCommunityNo("1");
                        config3.setCommunityName(CommonConstant.DEFAULT_COMMUNITY_NAME);
                        config3.setUrgingDate(ChargeUrgingLadderEnum.URGING_LADDER_FOUR);

                        config3.setTypeMsgList(list);
                        config3.setStatus(true);
                        config3.setCreateName("系统");
                        jdbcSession.insert(config3);
                    }
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }
        return null;
    }

    @Override
    public Page<ChargeUrgingConfig> findPage(JSONObject jsonObject) {
        FindPage<ChargeUrgingConfig> find = jdbcSession.findPage(ChargeUrgingConfig.class)
                .eq("deleted", false)
                .order("createTime", "asc");

        find.page(jsonObject);

        return find.exe();
    }

    @Override
    public List<ChargeUrgingConfig> findList(JSONObject jsonObject) {
        return jdbcSession.findArray(ChargeUrgingConfig.class)
                .eq("deleted", false)
                .eq("status", true)
                .exe();
    }

    @Override
    public Object save(ChargeUrgingConfig config) {
        if (checkDuplicateByUrgingDate(config.getUrgingDate(), config.getId(), config.getCommunityNo())){
            return Result.error(0, "已存在该欠费时段记录");
        }

        return jdbcSession.insert(config);
    }

    @Override
    public Object update(ChargeUrgingConfig config) {
        if (checkDuplicateByUrgingDate(config.getUrgingDate(), config.getId(), config.getCommunityNo())){
            return Result.error(0, "已存在该欠费时段记录");
        }

        return jdbcSession.updateById(config);
    }

    private boolean checkDuplicateByUrgingDate(ChargeUrgingLadderEnum urgingDate, String id, String communityNo) {
        List<ChargeUrgingConfig> list = getChargeUrgingConfigs(urgingDate, communityNo);
        return Objects.nonEmpty(list) && !list.get(0).getId().equals(id);
    }

    @Override
    public List<ChargeUrgingConfig> getChargeUrgingConfigs(ChargeUrgingLadderEnum urgingDate, String communityNo) {
        return jdbcSession.findArray(ChargeUrgingConfig.class)
                          .eq("communityNo", communityNo)
                          .eq("urgingDate", urgingDate)
                          .eq("deleted", false)
                          .exe();
    }

    @Override
    public Object pageChargeUrgingEmployee(JSONObject jsonObject) {
        return jdbcSession.findPage(ChargeUrgingEmployee.class)
                          .eq(jsonObject, "communityNo", "employeeNo")
                          .order("createTime", "DESC")
                          .page(jsonObject)
                          .exe();
    }

    @Override
    public Object deleteById(String id) {
        ChargeUrgingConfig result = Pool.get(ChargeUrgingConfig.class, id);
        if (result != null) {
            result.setDeleted(true);
            jdbcSession.updateById(result);
        }
        return 1;
    }

    @Override
    public Page<ChargeUrgingManage> findUrgingPage(JSONObject jsonObject) {

        FindPage<ChargeUrgingManage> find = jdbcSession.findPage(ChargeUrgingManage.class)
                .eq("deleted", false);
        find.like(jsonObject,"urgingNo", "communityNo", "communityName");
        //添加选中导出条件
        JSONArray exportIdList = jsonObject.getJSONArray("exportIdList");
        if(!Objects.isEmpty(exportIdList)){
            find.in("urgingNo",exportIdList);
        }

        find.order("createTime", "desc");
        find.page(jsonObject);

        return find.exe();
    }


    @Override
    public void pageUrgingExport(HttpServletRequest req, HttpServletResponse resp, JSONObject jsonObject) {
        jsonObject.put("pageNo", 1);
        jsonObject.put("pageSize", ExcelTool.MAX_ROWS);
        List<ChargeUrgingManage> list = findUrgingPage(jsonObject).getList();
        Assert.notEmpty(list,"导出失败！没有找到相关的催费数据");
        List<ChargeUrgingManageExcelVO> dtoList = ListUtils.copyList(list, ChargeUrgingManageExcelVO::new);
        excelTool.excelDownload(req,resp,dtoList,"催费列表导出");
    }


    @Override
    public Object insertManage(ChargeUrgingManage chargeUrgingManage, JSONObject paramJson) {
        chargeUrgingManage.setUrgingNo(CommonUtil.generateNumber("CF"));

        JSONObject jsonObject = new JSONObject();
        jsonObject.putAll(paramJson);
        jsonObject.put("communityNo", chargeUrgingManage.getCommunityNo());
        jsonObject.put("pageNo", 1);
        jsonObject.put("pageSize", 1000);
        // 如果是指定用户。目前产品方案是：页面填写手机号，然后去客户列表找这条记录，如果未找到直接放回
        if (Objects.nonEmpty(chargeUrgingManage.getReceiptMobile())) {
            try {
                // 获取账号
                JSONObject accountResult = doveClient.post("/auth/account/service/getAccount", (http) -> {
                    JSONObject body = new JSONObject();
                    body.put("mobile", chargeUrgingManage.getReceiptMobile());
                    http.setBody(body.toJSONString());
                });
                JSONObject account = accountResult.getJSONObject("data");
                if (account == null) {
                    return Result.error(0, "该用户尚未注册小程序");
                }

                jsonObject.put("userNo", account.getString("id"));
            } catch (Exception e) {
                return Result.error(0, "系统异常，请稍后重试");
            }
        }
        if (Objects.nonEmpty(chargeUrgingManage.getReceiptMobileList())) {
            Set<String> userNoSet = new HashSet<>();
            try {
                // 获取账号
                for (int i = 0; i < chargeUrgingManage.getReceiptMobileList().size(); i++) {
                    JSONObject accountResult = doveClient.post("/auth/account/service/getAccount", (http) -> {
                        JSONObject body = new JSONObject();
                        body.put("mobile", chargeUrgingManage.getReceiptMobile());
                        http.setBody(body.toJSONString());
                    });
                    JSONObject account = accountResult.getJSONObject("data");
                    if (account == null) {
                        // return Result.error(0, "该用户尚未注册小程序");
                        continue;
                    } else {
                        userNoSet.add(account.getString("id"));
                    }
                }

                if (Objects.isEmpty(userNoSet)) {
                    return Result.error(0, "该批次用户尚未在小程序进行注册");
                }

                jsonObject.put("listUserNo", new ArrayList<>(userNoSet));
            } catch (Exception e) {
                return Result.error(0, "系统异常，请稍后重试");
            }
        }

        try {
            final JSONObject finalMsgJson = getSendMsgJson(chargeUrgingManage);
            if (Objects.isNull(finalMsgJson)) {
                return Result.error(0, "不存在合适的模板或模板已被删除");
            }

            List<ChargeBillItemsVO> list = new ArrayList<>();
            // 根据小区，拉取欠费账单
            if (Objects.nonEmpty(chargeUrgingManage.getReceiptHouseUserList())) { // 指定
                for (int i = 0; i < chargeUrgingManage.getReceiptHouseUserList().size(); i++) {
                    String[] houseUser = chargeUrgingManage.getReceiptHouseUserList().get(i).split("-");
                    String houseNo = houseUser[0];
                    String userNo = houseUser[1];
                    jsonObject.put("houseNo", houseNo);
                    jsonObject.put("userNo", userNo);
                    list.addAll(listChargeBillItemsVO(jsonObject));
                }
            } else { // 全部
                list = listChargeBillItemsVO(jsonObject);
            }


            logger.info("自动催缴公司编号："+chargeUrgingManage.getCompanyNo()+"，小区编号："+chargeUrgingManage.getCommunityNo()+"，催缴方式"+chargeUrgingManage.getUrgingTypeMsg().getDesc()+"，欠费单数："+list.size());
            if (Objects.isEmpty(list)) {
                return Result.error(0, "催缴失败，没有可用的催缴账单");
            }
            chargeUrgingManage.setUrgingTotal(list.size());
            // 执行催缴
            list.forEach(e -> {
                try {
                    chargeUrgingManage.setHouseNo(e.getHouseNo());
                    JSONObject residentJson = null;
                    // 拿账户表
                    try {
                        residentJson = doveClient.post("/crm/assets/user/service/user/follow", http -> {
                            http.addParam("companyNo", chargeUrgingManage.getCompanyNo());
                            http.addParam("id", e.getUserNo());
                        });
                    } catch (Exception e1) {
                        residentJson = null;
                        logger.error("后台手动催缴获取用户异常："+e.getUserNo()+e1.getMessage(), e1);
                    }

                    if (Objects.isNull(residentJson)) {
                        logger.info("后台手动催缴账户为空：{}", e.getUserNo());
                        // continue
                    } else {
                        JSONObject residentDataJson = residentJson.getJSONObject("data");
                        FeeMsgDetailVO vo = getFeeMsgDetailVO(e, jsonObject);
                        JSONObject buildJson = listEmployeeByHouseNo(e.getBuildNo(), chargeUrgingManage.getCompanyNo());
                        logger.info("开始APP消息催缴，获取楼栋:{}管家数据：{}", e.getBuildNo(), buildJson.toJSONString());
                        JSONArray employeeNoArray = buildJson.getJSONArray("employeeNos");
                        if (Objects.nonEmpty(employeeNoArray)){
                            List<String> employeeNos = JSONObject.parseArray(employeeNoArray.toJSONString(), String.class);
                            logger.info("开始APP消息催缴，获取楼栋:{}管家ID：{}", e.getBuildNo(), employeeNos);
                            if (Objects.nonEmpty(employeeNos)) {
                                employeeNos.forEach(em -> {
                                    try {
                                        sendAppMsg(chargeUrgingManage, e, em, vo.getBillList());
                                    } catch (Exception e2) {
                                        logger.error("开始APP消息催缴，后台手动催缴异常"+e2.getMessage(), e2);
                                    }
                                });
                            }
                        } else {

                        }

                        ChargeUrgingUser user = getChargeUrgingUser(chargeUrgingManage, e, vo, residentDataJson);
                        UniformSendReqDto reqDto = getUniformSendReqDto(chargeUrgingManage, e, TemplateType.PAY_C_TASK_REMIND, e.getUserNo());
                        sendMsg(e, chargeUrgingManage, finalMsgJson, vo, user, reqDto, employeeNoArray);

                        jdbcSession.insert(user);
                    }
                } catch (Exception e1) {
                    logger.error("开始催缴，后台手动催缴异常："+e1.getMessage(), e1);
                }

            });
        } catch (Exception e) {
            logger.error("后台手动催缴异常:"+e.getMessage(), e);
            return Result.error(0, "系统异常，请稍后重试");
        }

        // 执行催缴
        return jdbcSession.insert(chargeUrgingManage);
    }

    private void sendMsg(ChargeBillItemsVO chargeBillItemsVO, ChargeUrgingManage chargeUrgingManage, JSONObject finalMsgJson, FeeMsgDetailVO vo, ChargeUrgingUser user, UniformSendReqDto reqDto, JSONArray employeeNoArray) throws Exception {
        UrgingEmployeeTypeEnum employeeTypeEnum = null;
        final List<String> billList = vo.getBillList();
        if (UrgingTypeEnum.MSG_SITE == chargeUrgingManage.getUrgingTypeMsg()) {
            employeeTypeEnum = UrgingEmployeeTypeEnum.URGING_INNER;
            sendMsgSite(vo, finalMsgJson, user, reqDto);
        } else if (UrgingTypeEnum.MSG_PUSH == chargeUrgingManage.getUrgingTypeMsg()) {
            employeeTypeEnum = UrgingEmployeeTypeEnum.URGING_WX;
            sendMsgPush(vo, user, reqDto);
        } else if (UrgingTypeEnum.MSG_PHONE == chargeUrgingManage.getUrgingTypeMsg()) {
            employeeTypeEnum = UrgingEmployeeTypeEnum.URGING_SMS;
            sendMsgPhone(vo, finalMsgJson, user, reqDto);
        } else {
            // continue 没有配置？？
        }

        // 根据楼栋管家插入催费数据
        final UrgingEmployeeTypeEnum finalEmployeeTypeEnum = employeeTypeEnum;
        if (!UrgingUserStatusEnum.URGING_SUCCESS.equals(user.getUrgingUserStatusEnum())
                || null == finalEmployeeTypeEnum || Objects.isEmpty(employeeNoArray)) {
            return;
        }
        List<String> employeeNos = JSONObject.parseArray(employeeNoArray.toJSONString(), String.class);
        if (Objects.isEmpty(employeeNos)) {
            return;
        }
        employeeNos.forEach(e -> {
            insertChargeUrgingEmployee(chargeBillItemsVO, e, billList, finalEmployeeTypeEnum);
        });
    }


    private UniformSendReqDto getUniformSendReqDto(ChargeUrgingManage chargeUrgingManage, ChargeBillItemsVO e, TemplateType templateType, String uuid) {
        UniformSendReqDto reqDto = new UniformSendReqDto();
        reqDto.setCompanyNo(chargeUrgingManage.getCompanyNo());
        reqDto.setMsgId(e.getHouseBillNo());
        reqDto.setBusinessTypeId(MessageBusinessEnum.MSG_BILL_PAY.getId());
        reqDto.setTemplateTypeId(templateType.getId());
        reqDto.setUserCreate(true);
        reqDto.setUuid(uuid);
        return reqDto;
    }

    private ChargeUrgingUser getChargeUrgingUser(ChargeUrgingManage chargeUrgingManage, ChargeBillItemsVO e, FeeMsgDetailVO vo, JSONObject residentDataJson) {
        ChargeUrgingUser user = Pool.newInstance(ChargeUrgingUser.class);
        user.setUrgingTaskNo(chargeUrgingManage.getId());
        user.setCommunityNo(e.getCommunityNo());
        user.setCommunityName(e.getCommunityName());
        user.setUserNo(e.getUserNo());
        user.setUserName(residentDataJson.getString("realname"));
        user.setMobile(residentDataJson.getString("mobile"));
        user.setBillAddress(e.getBillAddress());
        user.setAmountTotal(e.getAmountTotal());
        user.setUrgingUserStatusEnum(UrgingUserStatusEnum.URGING_INIT);
        user.setBillList(vo.getBillList());
        user.setHouseNo(e.getHouseNo());
        user.setCompanyNo(chargeUrgingManage.getCompanyNo());
        user.setDepartmentNo(chargeUrgingManage.getDepartmentNo());
        user.setDepartmentNos(chargeUrgingManage.getDepartmentNos());
        user.setDepartmentName(chargeUrgingManage.getDepartmentName());
        return user;
    }

    private void sendMsgPhone(FeeMsgDetailVO vo, JSONObject finalMsgJson, ChargeUrgingUser user, UniformSendReqDto reqDto) throws Exception {
        logger.info("后台催缴sendMsgPhone，模板参数:{}", finalMsgJson.toJSONString());
        JSONObject dataMsgJson = finalMsgJson.getJSONObject("data");
        user.setUrgingUserTypeEnum(UrgingUserTypeEnum.URGING_SMS);
        List<String> listPhone = Arrays.asList(user.getMobile());
        if (Objects.nonEmpty(listPhone)){
            reqDto.setPhoneList(listPhone);
            reqDto.setSmsDataParams(TemplateReplaceUtil.listTencentSmsParam(dataMsgJson.getString("content"), dataMsgJson.getString("tagArray"), vo));
            try {
                // 消息推送
                JSONObject sendResultJson = doveClient.post("/crm/message/service/smsSend", (http) -> {
                    http.addParam("temp", JSONObject.toJSONString(reqDto));
                });
                logger.info("后台手动催缴短信消息推送返回：{}", sendResultJson);
                setUrgingUserStatus(user, sendResultJson);
            } catch (Exception e1) {
                logger.error("后台手动催缴消息推送异常"+e1.getMessage(), e1);
            }
        }
    }

    private void sendMsgPush(FeeMsgDetailVO vo, ChargeUrgingUser user, UniformSendReqDto reqDto) {
        user.setUrgingUserTypeEnum(UrgingUserTypeEnum.URGING_WX_WEBCHAT);
        String wxchatData = getWxchatTemplate(TemplateType.PAY_C_TASK_REMIND, vo);
        reqDto.setWxChatData(wxchatData);
        String buffer = "houseNo=" + user.getHouseNo() + "&companyNo=" + user.getCompanyNo();
        reqDto.setPageParam(buffer);
        try {
            // 消息推送
            JSONObject sendResultJson = doveClient.post("/crm/message/service/wxchatSend", (http) -> {
                http.addParam("temp", JSONObject.toJSONString(reqDto));
            });
            logger.info("后台手动催缴微信消息推送返回：{}", sendResultJson);
            setUrgingUserStatus(user, sendResultJson);
        } catch (Exception e1) {
            logger.error("后台手动催缴消息推送异常"+e1.getMessage(), e1);
        }
    }

    private void sendMsgSite(FeeMsgDetailVO vo, JSONObject finalMsgJson, ChargeUrgingUser user, UniformSendReqDto reqDto) throws Exception {
        logger.info("后台催缴sendMsgSite，模板参数:{}", finalMsgJson.toJSONString());
        JSONObject dataMsgJson = finalMsgJson.getJSONObject("data");
        user.setUrgingUserTypeEnum(UrgingUserTypeEnum.URGING_INNER);
        reqDto.setTitle(finalMsgJson.getString("title"));
        reqDto.setInnerData(TemplateReplaceUtil.replace(dataMsgJson.getString("content"), dataMsgJson.getString("tagArray"), vo));
        try {
            // 消息推送
            JSONObject sendResultJson = doveClient.post("/crm/message/service/innerSend", (http) -> {
                http.addParam("temp", JSONObject.toJSONString(reqDto));
            });
            logger.info("后台手动催缴站内消息推送返回：{}", sendResultJson);
            setUrgingUserStatus(user, sendResultJson);
        } catch (Exception e1) {
            logger.error("后台手动催缴消息推送异常"+e1.getMessage(), e1);
        }
    }


    @Override
    public Object urgingUserList(JSONObject jsonObject){
        if (Objects.isEmpty(jsonObject.getString("urgingTaskNo"))){
            return Result.error(0, "缺少必填参数");
        }
        FindPage<ChargeUrgingUser> findPage = jdbcSession.findPage(ChargeUrgingUser.class)
                                                         .eq(jsonObject, "urgingTaskNo")
                                                         .like(jsonObject, "userName", "billAddress");
        return findPage.exe();
    }


    @Override
    public Object chargeUrgingTask() throws Exception {
        JSONArray array = getCorps();
        if(Objects.nonEmpty(array)) {
            for (Object obj : array) {
                JSONObject corp = (JSONObject) obj;

                String corpId = corp.getString("id");
                if (corpId.equals(Root.ROOT_ID)) {
                    continue;
                }

                ThreadLocalCache.current().setCorpId(corpId);

                JSONArray communitys = getCommunity(corpId);
                for (int i = 0; i < communitys.size(); i++) {
                    JSONObject communityJson = communitys.getJSONObject(i);
                    String communityId = communityJson.getString("id");
                    String communityName = communityJson.getString("name");

                    logger.info(ThreadLocalCache.current().getCorpId()+"自动催缴公司编号："+corpId+"，小区编号："+communityId);

                    List<ChargeUrgingConfig> configList = jdbcSession.findArray(ChargeUrgingConfig.class)
                                                                     // .eq("status", true)
                                                                     .eq("deleted", false)
                                                                     .exe();
                    LocalDateTime now = LocalDateTime.now();
                    DateTimeFormatter sdf = DateTimeFormatter.ofPattern("yyyy-MM");
                    try {
                        logger.info("自动催缴公司编号："+corpId+"，小区编号："+communityId+"，有效配置数："+configList.size());
                        for (int j = 0; j < configList.size(); j++) {
                            ChargeUrgingConfig config = configList.get(j);

                            ChargeUrgingConfig communityConfig = jdbcSession.findOne(ChargeUrgingConfig.class)
                                                                            .eq("communityNo", communityId)
                                                                            .eq("urgingDate", config.getUrgingDate())
                                                                            .eq("status", true)
                                                                            .eq("deleted", false)
                                                                            .exe();

                            if (Objects.nonNull(communityConfig)) {
                                config = communityConfig;
                            }

                            if (!config.isStatus()) {
                                continue;
                            }

                            JSONObject jsonObject = new JSONObject();
                            String startMonth = "";
                            String endMonth = "";
                            switch (config.getUrgingDate()) {
                                // case URGING_LADDER_ONE:
                                //     startMonth = sdf.format(now);
                                //     jsonObject.put("startMonth", startMonth);
                                //     break;
                                case URGING_LADDER_TWO:
                                    startMonth = sdf.format(now.plusMonths(-3).toLocalDate());
                                    endMonth = sdf.format(now.plusMonths(-1).toLocalDate());
                                    jsonObject.put("startMonth", startMonth);
                                    jsonObject.put("endMonth", endMonth);
                                    break;
                                case URGING_LADDER_FOUR:
                                    startMonth = sdf.format(now.plusMonths(-6).toLocalDate());
                                    endMonth = sdf.format(now.plusMonths(-4).toLocalDate());
                                    jsonObject.put("startMonth", startMonth);
                                    jsonObject.put("endMonth", endMonth);
                                    break;
                                case URGING_LADDER_THREE:
                                    endMonth = sdf.format(now.plusMonths(-6).toLocalDate());
                                    jsonObject.put("endMonth", endMonth);
                                    break;
                                default:
                                    break;
                            }

                            // 遍历催缴方式
                            for (String typeMsg : config.getTypeMsgList()) {
                                logger.info("自动催缴公司编号："+corpId+"，小区编号："+communityId+"，催缴方式："+typeMsg);
                                String[] temp = typeMsg.split("-");
                                String type = temp[0];
                                ChargeUrgingManage chargeUrgingManage = Pool.newInstance(ChargeUrgingManage.class);
                                chargeUrgingManage.setCompanyNo(corpId);
                                chargeUrgingManage.setCommunityNo(communityId);
                                chargeUrgingManage.setCommunityName(communityName);
                                chargeUrgingManage.setUrgingTypeMsg(Enums.getEnum(UrgingTypeEnum.class, type));
                                String messageNo = getMessageNo(chargeUrgingManage.getUrgingTypeMsg());
                                if (Objects.isEmpty(messageNo)) {
                                    continue;
                                }
                                chargeUrgingManage.setMessageNo(messageNo);

                                logger.info("自动催缴公司编号："+corpId+"，小区编号："+communityId+"，催缴方式："+chargeUrgingManage.getUrgingTypeMsg().getDesc()+"，模板编号："+messageNo);

                                String date = temp[1];
                                logger.info("自动催缴公司编号："+corpId+"，小区编号："+communityId+"，date："+date+"，周？"+now.getDayOfWeek().getValue()+"，月？"+now.getDayOfMonth());
                                if ("1".equals(date) ) { // 每日一次
                                    insertManage(chargeUrgingManage, jsonObject);
                                } else if ("2".equals(date) && now.getDayOfWeek().getValue() == 1) { // 每周一次
                                    insertManage(chargeUrgingManage, jsonObject);
                                } else if ("3".equals(date) && now.getDayOfMonth() == 1) { // 每月一次
                                    insertManage(chargeUrgingManage, jsonObject);
                                } else {

                                }
                            }
                        }
                    } catch (Exception e) {
                        logger.info("定时催缴任务"+e.getMessage(), e);
                    }
                }
            }
        }
        return Result.success();
    }

    private String getMessageNo(UrgingTypeEnum typeEnum){
        String messageNo = "";
        // 获取消息推送配置
        TemplateType templateType = TemplateType.PAY_C_TASK_REMIND;
        try {
            JSONObject configJson = doveClient.post("/crm/message/global/config/service/get", (http) -> {
                http.addParam("templateType", templateType.getId());
            });
            if (configJson.getIntValue("code") == 200) {
                List<Map<String, String>>  mapObj = new ArrayList<>();
                JSONObject configDataJson = configJson.getJSONObject("data");

                if (UrgingTypeEnum.MSG_SITE == typeEnum) {
                    JSONObject tempJson = configDataJson.getJSONObject("messageTemplateInner");
                    if (Objects.nonNull(tempJson)) {
                        messageNo = tempJson.getString("id");
                    }
                } else if (UrgingTypeEnum.MSG_PUSH == typeEnum) {

                    String wxchatTemplate = configDataJson.getString("wxchatTemplate");
                    JSONObject wxchatJson = doveClient.post("/wechat/template/setting/service/get", (http) -> {
                        http.addParam("id", wxchatTemplate);
                    });
                    if (configJson.getIntValue("code") == 200) {
                        JSONObject wxchatDataJson = wxchatJson.getJSONObject("data");
                        if (Objects.nonNull(wxchatDataJson)) {
                            messageNo = wxchatDataJson.getString("id");
                        } else {
                        }
                    } else {
                    }
                } else if (UrgingTypeEnum.MSG_PHONE == typeEnum) {

                    JSONObject tempJson = configDataJson.getJSONObject("messageTemplateSms");
                    if (Objects.nonNull(tempJson)) {
                        messageNo = tempJson.getString("id");
                    }
                } else {
                    // continue
                }

            }
        } catch (Exception e){
            logger.error(e.getMessage(), e);
        }
        return messageNo;
    }

    /**
     * 获取所有企业信息
     * @return
     * @throws Exception
     */
    private JSONArray getCorps() throws Exception {
        JSONObject result = doveClient.post("/admin/service/corp/list",(http)->{});

        if (result.getIntValue("code") == 200) {
            return result.getJSONArray("data");
        }

        return null;
    }

    public JSONArray getCommunity(String companyNo) throws Exception {
        try {
            JSONObject result = doveClient.post("/basic/community/service/list", http->{
                http.addParam("companyNo", companyNo);
            });

            JSONArray data = result.getJSONArray("data");

            if (Objects.isNull(data)) {
                return new JSONArray();
            }

            return data;
        } catch (Exception e){
            logger.error("定时催缴拉取小区数据异常"+e.getMessage(), e);
            return new JSONArray();
        }
    }

    /**
     * 查询该账单编号是否催缴
     * @param billNo 账单编号
     * @return true 已催缴
     */
    @Override
    public boolean isRemindUrgingUser(String billNo){

        return jdbcSession.findArray(ChargeUrgingUser.class)
                .like("billList", billNo)
                .exe().size() > 0;
    }

    private void setUrgingUserStatus(ChargeUrgingUser user, JSONObject sendResultJson) {
        if (sendResultJson.getIntValue("code") == 200) {
            user.setUrgingUserStatusEnum(UrgingUserStatusEnum.URGING_SUCCESS);
        } else {
            user.setUrgingUserStatusEnum(UrgingUserStatusEnum.URGING_FAIL);
            user.setRemark(sendResultJson.getString("message"));
        }
    }

    private FeeMsgDetailVO getFeeMsgDetailVO(ChargeBillItemsVO e, JSONObject jsonObject) throws Exception {
        JSONObject tempJson = new JSONObject();
        tempJson.put("communityNo", e.getCommunityNo());
        tempJson.put("houseNo", e.getHouseNo());
        tempJson.put("userNo", e.getUserNo());
        tempJson.put("ownerName", e.getChargeName());
        tempJson.put("startMonth", jsonObject.getString("startMonth"));
        tempJson.put("endMonth", jsonObject.getString("endMonth"));
        return chargeArrearsService.getFeeMsgDetail(tempJson);
    }

    private JSONObject getSendMsgJson(ChargeUrgingManage chargeUrgingManage) throws Exception {
        JSONObject msgJson = null;
        if (UrgingTypeEnum.MSG_SITE == chargeUrgingManage.getUrgingTypeMsg()) {
            msgJson = doveClient.post("/crm/message/inner/service/get", http -> {
                http.addParam("companyNo", chargeUrgingManage.getCompanyNo());
                http.addParam("id", chargeUrgingManage.getMessageNo());
            });
            logger.info("催缴请求站内信模板返回参数：{}", msgJson.toJSONString());
        } else if (UrgingTypeEnum.MSG_PHONE == chargeUrgingManage.getUrgingTypeMsg()) {
            msgJson = doveClient.post("/crm/message/sms/service/get", http -> {
                http.addParam("companyNo", chargeUrgingManage.getCompanyNo());
                http.addParam("id", chargeUrgingManage.getMessageNo());
            });
            logger.info("催缴请求短信模板返回参数：{}", msgJson.toJSONString());
        } else if (UrgingTypeEnum.MSG_PUSH == chargeUrgingManage.getUrgingTypeMsg()) {
            msgJson = new JSONObject();
        } else {
            // continue
        }
        return msgJson;
    }

    private void sendAppMsg(ChargeUrgingManage chargeUrgingManage, ChargeBillItemsVO e, String uuid, List<String> billList) throws Exception {
        UniformSendReqDto reqDtoToB = getUniformSendReqDto(chargeUrgingManage, e, TemplateType.PAY_B_TASK_REMIND, uuid);
        // 获取消息推送配置文件
        JSONObject configJson = doveClient.post("/crm/message/global/config/service/get", (http) -> {
            http.addParam("templateType", reqDtoToB.getTemplateTypeId());
        });

        if (configJson.getIntValue("code") == 200) {
            JSONObject dataJson = configJson.getJSONObject("data");

            logger.info("催缴APP配置信息：{}", dataJson.toJSONString());

            JSONObject app = dataJson.getJSONObject("messageTemplateApp");
            if (dataJson.getBooleanValue("appSend") && Objects.nonNull(app)) {
                String param = String.format("?companyNo=%s&houseNo=%s", chargeUrgingManage.getCompanyNo(), e.getHouseNo());
                reqDtoToB.setAppToUrl(webUrlConfig.getUrl("/web-app/?page=charge/list"+ URLEncoder.encode(param, "UTF-8")));

                reqDtoToB.setTitle(app.getString("title"));
                reqDtoToB.setAppData(TemplateReplaceUtil.replace(app.getString("content"), app.getString("tagArray"), chargeUrgingManage));

                String dtoString = JSONObject.toJSONString(reqDtoToB);
                logger.info("催缴消息推送请求参数：{}", dtoString);
                try {
                    // 消息推送
                    JSONObject sendResultJson = doveClient.post("/crm/message/service/appSend", (http) -> {
                        http.addParam("temp", dtoString);
                    });
                    logger.info("后台手动催缴APP消息推送返回：{}", sendResultJson);
                    if (sendResultJson.getIntValue("code") == 200) {
                        insertChargeUrgingEmployee(e, uuid, billList, UrgingEmployeeTypeEnum.URGING_APP);
                    } else {

                    }
                } catch (Exception e1) {
                    logger.error("后台手动催缴APP消息推送异常"+e1.getMessage(), e1);
                }
            }
        } else {
            logger.info("催缴APP获取配置失败");
        }
    }

    private void insertChargeUrgingEmployee(ChargeBillItemsVO e, String uuid, List<String> billList, UrgingEmployeeTypeEnum employeeTypeEnum) {
        ChargeUrgingEmployee employee = Pool.newInstance(ChargeUrgingEmployee.class);
        employee.setCommunityNo(e.getCommunityNo());
        employee.setCommunityName(e.getCommunityName());
        employee.setEmployeeNo(uuid);
        employee.setBuildNo(e.getBuildNo());
        employee.setHouseNo(e.getHouseNo());
        employee.setBillAddress(e.getBillAddress());
        employee.setUserNo(e.getUserNo());
        employee.setUserName(e.getChargeName());
        employee.setResidentsType(e.getResidentsType());
        employee.setMobile(e.getMobile());
        employee.setEmployeeTypeEnum(employeeTypeEnum);
        employee.setBillList(billList);
        jdbcSession.insert(employee);
    }

    private List<ChargeBillItemsVO> listChargeBillItemsVO(JSONObject jsonObject) {
        Page<ChargeBillItemsVO> page = chargeArrearsService.findCommunityPage(jsonObject);
        List<ChargeBillItemsVO> list = page.getList();
        int totalPage = page.getTotalPage();
        for (int i = 2; i <= totalPage; i++) {
            jsonObject.put("pageNo", i); // 重置页数
            Page<ChargeBillItemsVO> tempPage = chargeArrearsService.findCommunityPage(jsonObject);
            list.addAll(tempPage.getList());
        }
        return list;
    }

    private String getWxchatTemplate(TemplateType templateType, FeeMsgDetailVO vo) {
        JSONObject data = new JSONObject();

        if(TemplateType.PAY_C_TASK_REMIND == templateType){
            data.put("first", buildMpMessageData("您有物业费用待缴"));
            // 小区
            data.put("keyword1", buildMpMessageData(vo.getCommunityName()));
            // 房屋
            data.put("keyword2", buildMpMessageData(vo.getAddress()));
            // 本期物业费
            data.put("keyword3", buildMpMessageData(BigDecimalUtils.format(vo.getCurrentAmountTotal()).toPlainString()));
            // 历史欠费
            data.put("keyword4", buildMpMessageData(BigDecimalUtils.format(vo.getHistoryAmountTotal()).toPlainString()));
            // 物业费总计
            data.put("keyword5", buildMpMessageData(BigDecimalUtils.format(vo.getAllAmountTotal()).toPlainString()));

            data.put("remark", buildMpMessageData("请核对账单进行缴费，如有疑问，请咨询物业公司。感谢您的支持与关注！"));
            return data.toJSONString();
        } else {
            return null;
        }
    }

    private JSONObject buildMpMessageData(String value) {
        JSONObject json = new JSONObject();
        json.put("value", value);
        return json;
    }

    private JSONObject listEmployeeByHouseNo(String houseNo, String companyNo) {
        try {
            JSONObject buildingResult = doveClient.post("/basic/building/service/get", (http) -> {
                Map<String, String> map =new HashMap<>();
                map.put("companyNo", companyNo);
                http.setHeaders(map);
                JSONObject body = new JSONObject();
                body.put("id", houseNo);
                http.setBody(body.toJSONString());
            });

            if (buildingResult.getIntValue("code")== 200) {
                JSONObject buildingJson=buildingResult.getJSONObject("data");
                if(org.coraframework.util.Objects.nonNull(buildingJson)){
                    return buildingJson;
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return new JSONObject();
        }
        return new JSONObject();
    }

}
